package com.amigo.online.consumer.video.util;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
 * 从视频中提取音频 
 */
@Component
public class FFMpegUtil {
	
	private static final Logger logger = Logger.getLogger(FFMpegUtil.class);
	private static final String HOME_PATH;
    private static String FFMPEG_PATH;
    private static String TMP_PATH;
	
	@Value("${ffmpeg_path}")
	public void setFfmpegPath(String ffmpegPath) {
		FFMPEG_PATH = ffmpegPath;
	}
	@Value("${tmp_path}")
	public void setTemPath(String tmpPath) {
		TMP_PATH = tmpPath;
	}
	
	static {
        HOME_PATH = System.getProperty("user.home");// windows下：C:\Users\用户名\  linux下：/root
        logger.info("static home path : " + HOME_PATH);
    }
    
	
    /**
     * 压缩视频
     * @param videoUrl
     * @param videoName
     * @return 返回值为null或者"" 表示失败，成功返回fileId
     */
    @SuppressWarnings("finally")
	public static String compressVideo(String videoUrl,String videoName) {
    	String fileId = "";
    	try {
    		String type = videoUrl.indexOf(".") != -1
					? videoUrl.substring(videoUrl.lastIndexOf(".") + 1, videoUrl.length())
					: null;
			if (type != null) {
				logger.error("未获取到文件类型" + videoUrl);
				return "";
			}
	    	String targetUrl = (HOME_PATH + TMP_PATH + videoName + "_compress."+type).trim();
	    	String command = FFMPEG_PATH + "ffmpeg -i" + videoUrl +"-b 600K " + targetUrl;
	    	logger.info("compressVideo  command : " + command);
	        Process process = Runtime.getRuntime().exec(command);
	        //这里我们需要对流进行处理,防止process.waitFor()方法产生死锁
	        InputStream errorStream = process.getErrorStream();
	        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
	        BufferedReader br = new BufferedReader(inputStreamReader);
	        while (br.readLine()!= null) {
	        }
	        if (br != null) {
	            br.close();
	        }
	        if (inputStreamReader != null) {
	            inputStreamReader.close();
	        }
	        if (errorStream != null) {
	            errorStream.close();
	        }
	        process.waitFor();
	        fileId = FastDFSClient.uploadFile(input2byte(process.getInputStream()),null);
	        if(fileId == null || "".equals(fileId)) {
	        	logger.error("视频文件上传失败,音频路径：" + targetUrl);
	        }
	        Runtime.getRuntime().exec("rm -rf "+ videoUrl);
	        Runtime.getRuntime().exec("rm -rf "+ targetUrl);
	        process.destroy();
    	}catch (Exception e) {
    		fileId = "";
    		logger.error("音频提取失败，视频地址："+videoUrl, e);
        }
    	return fileId;
    }
    
    
    /**
     * @param videoUrl 原视频的路径
     * @param musicUrl 音频的路径
     * @param videoOutPath   视频与音频结合之后的视频的路径
     * @param time           视频的长度 ,单位为 s
     * @throws Exception
     */
    // 将视频和音频结合，并指定视频的长度，同时生成结合之后的视频文件
    // ffmpeg -i tsd.mp4 -i "周笔畅+-+最美的期待.mp3" -t "time" -y new.avi
    @SuppressWarnings("finally")
	public static String convetor(String videoUrl,String videoName, String musicUrl, double time)
            throws Exception {
    	String fileId = "";
    	try {
	    	String type = videoUrl.indexOf(".") != -1
					? videoUrl.substring(videoUrl.lastIndexOf(".") + 1, videoUrl.length())
					: null;
			if (type != null) {
				logger.error("未获取到文件类型" + videoUrl);
				return "";
			}
			String targetUrl = (HOME_PATH + TMP_PATH + videoName + "_convetor."+type).trim();
	    	String command = FFMPEG_PATH + "ffmpeg -i" + videoUrl +"-i"+musicUrl +"-t" + time+"-y"+targetUrl;
	    	logger.info("compressVideo  command : " + command);
	        Process process = Runtime.getRuntime().exec(command);
	        //这里我们需要对流进行处理,防止process.waitFor()方法产生死锁
	        InputStream errorStream = process.getErrorStream();
	        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
	        BufferedReader br = new BufferedReader(inputStreamReader);
	        while (br.readLine() != null) {
	        }
	        if (br != null) {
	            br.close();
	        }
	        if (inputStreamReader != null) {
	            inputStreamReader.close();
	        }
	        if (errorStream != null) {
	            errorStream.close();
	        }
	        process.waitFor();
	        process.destroy();
	        fileId =  compressVideo(targetUrl,videoName);
    	}catch (Exception e) {
    		fileId = "";
    		logger.error("音视频合成失败，视频地址："+videoUrl+"音频地址："+ musicUrl + e);
        }
    	return fileId;

    }
    
    
    /**
     * @param videoUrl 原视频的路径
     * @param musicUrl 音频的路径
     * @param videoOutPath   视频与音频结合之后的视频的路径
     * @param time           视频的长度 ,单位为 s
     * @throws Exception
     */
    // 将视频和音频结合，并指定视频的长度，同时生成结合之后的视频文件
    // ffmpeg -i tsd.mp4 -i "周笔畅+-+最美的期待.mp3" -t "time" -y new.avi
    @SuppressWarnings("finally")
	public static String shunt(String videoUrl,String videoName) throws Exception {
    	String targetUrl = "";
    	try {
	    	String type = videoUrl.indexOf(".") != -1
					? videoUrl.substring(videoUrl.lastIndexOf(".") + 1, videoUrl.length())
					: null;
			if (type != null) {
				logger.error("未获取到文件类型" + videoUrl);
				return "";
			}
			targetUrl = (HOME_PATH + TMP_PATH + videoName + "_silent."+type).trim();
	    	String command = FFMPEG_PATH + "ffmpeg -i" + videoUrl +" -vcodec copy –an " + targetUrl;
	    	logger.info("compressVideo  command : " + command);
	        Process process = Runtime.getRuntime().exec(command);
	        //这里我们需要对流进行处理,防止process.waitFor()方法产生死锁
	        InputStream errorStream = process.getErrorStream();
	        InputStreamReader inputStreamReader = new InputStreamReader(errorStream);
	        BufferedReader br = new BufferedReader(inputStreamReader);
	        while (br.readLine() != null) {
	        }
	        if (br != null) {
	            br.close();
	        }
	        if (inputStreamReader != null) {
	            inputStreamReader.close();
	        }
	        if (errorStream != null) {
	            errorStream.close();
	        }
	        process.waitFor();
	        process.destroy();
    	}catch (Exception e) {
    		e.printStackTrace();
    		logger.error("视频剥离失败："+videoUrl+"视频地址："+ targetUrl + e);
    		targetUrl = "";
        }
    	return targetUrl;
    }
    
    

    public static final byte[] input2byte(InputStream inStream)  throws IOException {  
    	ByteArrayOutputStream swapStream = new ByteArrayOutputStream();  
        byte[] buff = new byte[100];  
        int rc = 0;  
        while ((rc = inStream.read(buff, 0, 100)) > 0) {  
        	swapStream.write(buff, 0, rc);  
        }  
        byte[] in2b = swapStream.toByteArray();  
        return in2b;  
    }  
}
